package impl

import (
	"context"
	"errors"
	"time"

	"gitee.com/hexug/vblog/tree/master/api/apps/post"
	"gitee.com/hexug/vblog/tree/master/api/apps/tag"
	"gitee.com/hexug/vblog/tree/master/api/validate"
)

func (i *impl) CreateBlog(ctx context.Context, request *post.CreateBlogRequest) (*post.Blog, error) {
	if err := validate.V().Struct(request); err != nil {
		return nil, err
	}
	b := post.NewBlog(request)
	res := i.Db.WithContext(ctx).Create(b)
	if res.Error != nil {
		return nil, res.Error
	}
	return b, nil
}

// UpdateBlog 更新博客
func (i *impl) UpdateBlog(ctx context.Context, request *post.UpdateBlogRequest) (*post.Blog, error) {
	if err := validate.V().Struct(request); err != nil {
		return nil, err
	}
	gdr := post.NewDeleteOrGetBlogRequest(request.Id)
	b, err := i.GetDetailsBlog(ctx, gdr)
	if err != nil {
		return nil, err
	}
	t := time.Now().Unix()
	if b.Status != request.Status && request.Status == post.PUBLISHED {
		b.PulishedAt = t
	}
	b.UpdatedAt = t
	if request.UpdateMod == post.PATCH {
		b.CreateBlogRequest = request.CreateBlogRequest
		res := i.Db.WithContext(ctx).Updates(b)
		if res.Error != nil {
			return nil, res.Error
		}
		return b, nil
	}
	if request.UpdateMod == post.PUT {
		created_at := b.CreatedAt
		pulished_at := b.PulishedAt
		b = &post.Blog{}
		b.CreateBlogRequest = request.CreateBlogRequest
		b.Id = request.Id
		b.CreatedAt = created_at
		b.PulishedAt = pulished_at
		res := i.Db.WithContext(ctx).Save(b)
		if res.Error != nil {
			return nil, res.Error
		}
		return b, nil
	}
	return nil, errors.New("异常")
}

// DeleteBlog 删除博客
func (i *impl) DeleteBlog(ctx context.Context, request *post.DeleteOrGetBlogRequest) (*post.Blog, error) {
	b, err := i.GetDetailsBlog(ctx, request)
	if err != nil {
		return nil, err
	}
	res := i.Db.WithContext(ctx).Where("id=?", request.Id).Delete(&post.Blog{})
	if res.Error != nil {
		return nil, res.Error
	}
	tags := []int{b.Id}
	reqtag := tag.NewDeleteOrGetTagRequest()
	reqtag.BlogIds = &tags
	_, _ = i.Tag.DeleteTag(ctx, reqtag)
	return b, nil
}

// QueryBlog 查询博客
func (i *impl) QueryBlog(ctx context.Context, request *post.QueryBlogRequest) (*post.BlogsList, error) {
	//if request == post.NewQueryBlogRequest() {
	//	return nil, errors.New("参数为空。")
	//}
	// fmt.Println(request)
	db := i.Db.WithContext(ctx).Order("updated_at DESC,created_at DESC")
	if request.Status > 0 {
		db = db.Where("status=?", request.Status)
	}
	if request.Keywords != "" {
		db = db.Where("title like ?", `%`+request.Keywords+`%`)
	}
	pagesize := request.PageSize
	if request.PageSize > 30 || request.PageSize < 1 {
		pagesize = 5
	}
	pagenum := request.PageNum
	if pagenum > 30 || pagenum < 1 {
		pagenum = 1
	}
	// fmt.Println(pagenum, pagesize, request)
	blogs := post.NewBlogsList()
	db.Table("blogs").Count(&blogs.Total)
	res := db.Offset((pagenum - 1) * pagesize).Limit(pagesize).Find(&blogs.Items)
	// fmt.Println(blogs, "==============")
	if res.Error != nil {
		return nil, res.Error
	}
	if res.RowsAffected == 0 {
		return nil, errors.New("未找到博客。")
	}

	tags := make([]int, 0, pagesize)
	for _, b := range blogs.Items {
		tags = append(tags, b.Id)
	}
	reqtag := tag.NewDeleteOrGetTagRequest()
	reqtag.BlogIds = &tags
	tl, _ := i.Tag.GetTag(ctx, reqtag)
	if tl != nil {
		for _, t := range tl.Items {
			for _, b := range blogs.Items {
				if t.BlogId == b.Id {
					b.TagList = append(b.TagList, t)
					break
				}
			}
		}
	}
	return blogs, nil
}

// GetDetailsBlog 获取博客详情
func (i *impl) GetDetailsBlog(ctx context.Context, request *post.DeleteOrGetBlogRequest) (*post.Blog, error) {
	if err := validate.V().Struct(request); err != nil {
		return nil, err
	}
	b := &post.Blog{}
	res := i.Db.WithContext(ctx).Where("id=?", request.Id).Find(b)
	if res.Error != nil {
		return nil, res.Error
	}
	if res.RowsAffected == 0 {
		return nil, errors.New("未找到博客。")
	}
	tags := []int{b.Id}
	reqtag := tag.NewDeleteOrGetTagRequest()
	reqtag.BlogIds = &tags
	tl, _ := i.Tag.GetTag(ctx, reqtag)
	if tl != nil {
		b.TagList = append(b.TagList, tl.Items...)
	}
	return b, nil
}
